package com.gin.kotlin.gf2gamecommunity.viewmodel

import androidx.lifecycle.ViewModel
import com.gin.kotlin.enums.QueryType
import com.gin.kotlin.gf2gamecommunity.app.App
import com.gin.kotlin.gf2gamecommunity.base.livedata.CachedLiveData
import com.gin.kotlin.gf2gamecommunity.callback.AbstractNothingCallback
import com.gin.kotlin.response.Res
import com.gin.kotlin.response.task.CurrentSignInStatus
import com.gin.kotlin.response.task.CurrentTaskList
import com.gin.kotlin.response.task.MonthSignInStatus
import kotlinx.coroutines.delay
import retrofit2.Call
import retrofit2.await
import retrofit2.awaitResponse

/**
 * 日常ViewModel
 * @constructor
 */
class DailyViewModel : ViewModel() {
    private var loadingSignIn = false
    private var loadingDailyAll = false

    val current = CachedLiveData<Res<CurrentSignInStatus>, CurrentSignInStatus>(
        requestMethod = { App.INSTANCE.api.taskApi.getCurrentSignInStatus() },
        bodyTransform = { it.data },
    )
    val month = CachedLiveData<Res<MonthSignInStatus>, MonthSignInStatus>(
        requestMethod = { App.INSTANCE.api.taskApi.getMonthSignInStatus() },
        bodyTransform = { it.data },
    )
    val tasks = CachedLiveData<Res<CurrentTaskList>, CurrentTaskList>(
        requestMethod = { App.INSTANCE.api.taskApi.getCurrentTaskList() },
        bodyTransform = { it.data },
    )

    fun signInCall() = App.INSTANCE.api.taskApi.signIn()

    fun signIn(onSuccess: () -> Unit = {}) {
        if (loadingSignIn) return
        loadingSignIn = true
        signInCall().enqueue(object : AbstractNothingCallback() {
            override fun onSuccess(message: String) {
                App.toast(message)
                onSuccess()
                // 签到成功后刷新当前签到状态
                current.fetch(true)
            }

            override fun finally(call: Call<Res<Nothing>?>) {
                loadingSignIn = false
            }
        })
    }

    /**
     * 一键完成所有日常任务
     * @param onProgressUpdated 完成一次请求的回调
     * @param onComplete 操作全部完成的回调
     */
    suspend fun dailyAll(onProgressUpdated: (message: String) -> Unit = {}) {
        if (loadingDailyAll) return
        loadingDailyAll = true
        try {//  主题列表
            val topics = api().list(queryType = QueryType.NORMAL, categoryId = 1).await().data?.list?.takeIf { it.isNotEmpty() } ?: return

            // 浏览3次
            topics.take(3).forEach {
                try {
                    val response = api().get(it.topicId).awaitResponse()
                    val code = response.code()
                    if (code == 200) {
                        onProgressUpdated("浏览主题: ${it.title}")
                    } else {
                        onProgressUpdated("浏览异常: ${it.title}, code: $code")
                    }
                    delay(200)
                } catch (e: Exception) {
                    onProgressUpdated("浏览失败: ${e.message}")
                }
            }

            // 点赞3次
            topics.filter { !it.isLike }.take(3).forEach {
                try {
                    val response = api().like(it.topicId).awaitResponse()
                    val code = response.code()
                    if (code == 200) {
                        onProgressUpdated("点赞主题: ${it.title}")
                    } else {
                        onProgressUpdated("点赞异常: ${it.title}, code: $code")
                    }
                    delay(200)
                } catch (e: Exception) {
                    onProgressUpdated("点赞失败: ${e.message}")
                }
            }
            // 分享1次
            topics.take(1).forEach {
                try {
                    val response = api().share(it.topicId).awaitResponse()
                    val code = response.code()
                    if (code == 200) {
                        onProgressUpdated("分享主题: ${it.title}")
                    } else {
                        onProgressUpdated("分享异常: ${it.title}, code: $code")
                    }
                    delay(200)
                } catch (e: Exception) {
                    onProgressUpdated("分享失败: ${e.message}")
                }
            }
        } catch (e: Exception) {
            onProgressUpdated(e.message.toString())
        } finally {
            loadingDailyAll = false
            // 更新任务状态
            tasks.fetch(true)
        }
    }


    fun fetchAll(force: Boolean = false) {
        current.fetch(force)
        month.fetch(force)
        tasks.fetch(force)
    }

    fun clearAll() {
        current.clear()
        month.clear()
        tasks.clear()
    }

    private fun api() = App.INSTANCE.api.topicApi

    companion object {
        private val TAG = DailyViewModel::class.java.simpleName
    }
}